//
//  RootViewController.m
//  upnpxdemo
//
//  Created by haiyong on 13-8-25.
//  Copyright (c) 2013年 Bruno Keymolen. All rights reserved.
//

#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <net/if.h>
#import <QuartzCore/QuartzCore.h>
#import "JSONKit.h"
#import "RootViewController.h"
#import "MoreViewController.h"
#import "WLANView.h"
#import "AKTabBarController.h"
#import "ControlViewController.h"
#import "WlanSelectViewController.h"
#import "DeviceMoreViewController.h"
#import "MusicViewController.h"
#import <MediaPlayer/MediaPlayer.h>
#import "MJRefresh.h"
#import "WiimuUpnp.h"
#import "MMProgressHUD.h"

@interface RootViewController ()
<WiimuUpnpDelegate,MPMediaPickerControllerDelegate,MJRefreshBaseViewDelegate>
{
    MJRefreshHeaderView *_header;
    NSDictionary * currentSelectedDevice;
    NSMutableArray * deviceArr;
}

@end

@implementation RootViewController
@synthesize menuView;

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    if(self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
    {
        isRefresh = NO;
        
        //timer
        timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];

        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //mj
    _header = [MJRefreshHeaderView header];
    _header.scrollView = self.menuView;
    _header.delegate = self;
    
    [MMProgressHUD setPresentationStyle:MMProgressHUDPresentationStyleExpand];
    
    deviceArr = [[NSMutableArray alloc] init];
    
    [[WiimuUpnp sharedInstance] addDelegate:self];
    [[WiimuUpnp sharedInstance] beginSSDP:devWifiAudio];
    
    [GlobalInfo sharedInstance].upnpArray = deviceArr;

    //发生连接错误返回时
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(errorComeBack) name:@"ErrorComeBack" object:nil];

    //开始更新
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(beginCheckUpdate) name:@"BeginCheckUpdate" object:nil];
    [self prepareData];

    [self prepareUI];
    
//    MPMediaQuery *query = [[MPMediaQuery alloc] init];
//    
//    [query addFilterPredicate: [MPMediaPropertyPredicate
//                                predicateWithValue: @"Moribund the Squirrel"
//                                forProperty: MPMediaItemPropertyArtist]];
//    // Sets the grouping type for the media query
//    [query setGroupingType: MPMediaGroupingAlbum];
//    
//    MPMediaQuery *everything = [[MPMediaQuery alloc] init];
//    NSLog(@"Logging items from a generic query...");
//    NSArray *itemsFromGenericQuery = [everything items];
//    for (MPMediaItem *song in itemsFromGenericQuery) {
//        NSURL *songTitle = [song valueForProperty: MPMediaItemPropertyAssetURL];
//        NSLog (@"%@", songTitle);
//    }
}

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    self.navigationController.navigationBar.hidden = NO;
    
    //当界面退回到首页 相当于不属于任何设备
    //停止检查固件更新
    isGettingUpdate = NO;
    [GlobalInfo sharedInstance].isVersionNew = NO;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Relinquish ownership any cached data, images, etc that aren't in use.
}

- (void)dealloc
{
    [[WiimuUpnp sharedInstance] stopSSDP];
}

-(IBAction)moreButtonPressed:(id)sender
{
    MoreViewController * mvc = [[MoreViewController alloc] initWithNibName:@"MoreViewController" bundle:nil];
    [self.navigationController pushViewController:mvc animated:YES];
}

#pragma mark - navigation methods
-(NSString *)navigationBarTitle
{
    return NSLocalizedString(@"ROOT_TITLE",@"");
}

-(BOOL)isNavigationBackEnabled
{
    return NO;
}

#pragma mark -
#pragma mark UITableView Delegate & Datasource
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 60;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [deviceArr count];
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    else
    {
        for(UIView * subview in [cell.contentView subviews])
        {
            [subview removeFromSuperview];
        }
    }

    // Configure the cell.
    
    NSDictionary * dic = [deviceArr objectAtIndex:indexPath.row];
    
    UIImageView * imageview = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"upnpdevice.png"]];
    [cell.contentView addSubview:imageview];
    [imageview setFrame:CGRectMake(10, 10, 40, 40)];
    
    UILabel * label = [[UILabel alloc] init];
    label.frame = CGRectMake(60, 10, 200, 40);
    [cell.contentView addSubview:label];
    label.backgroundColor = [UIColor clearColor];
    label.text = dic[@"friendlyName"];
    
    UIImageView * rightImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"rightarrow1.png"]];
    rightImage.frame = CGRectMake(tableView.frame.size.width-40, 20, 10, 20);
    [cell.contentView addSubview:rightImage];
    
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:YES];
    
    NSDictionary * dic = [deviceArr objectAtIndex:indexPath.row];
    
    NSRange endRange = [dic[@"baseURL"] rangeOfString:@":" options:NSBackwardsSearch];
    
    if(endRange.location == NSNotFound)
    {
        return;
    }
    
    NSString * baseUrl = [dic[@"baseURL"] substringToIndex:endRange.location];
    
    [GlobalInfo sharedInstance].currentBaseURL = baseUrl;
    currentSelectedDevice = [deviceArr objectAtIndex:indexPath.row];
    
    [self getDeviceInfo];
}

#pragma mark -
#pragma mark private methods
-(void)popWLANView
{
    NSString * iosStr = nil;
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        iosStr = @"WLANView";
    } else {
        iosStr = @"WLANView_iPad";
    }
    
    WLANView * wlv = [[[NSBundle mainBundle] loadNibNamed:iosStr owner:self options:nil] lastObject];
    [wlv getDeviceInformations];
    wlv.completionBlock = ^() {
        [self getPlayerStatus];
    };
    [self.view addSubview:wlv];
}

-(void)getPlayerStatus
{
    [[GlobalService sharedInstance] getPlayerStatus:self];
    
    [MMProgressHUD showWithStatus:@"loading..."];
}


-(void)getDeviceInfo
{
    [[GlobalService sharedInstance] getDeviceInfo:self url:[GlobalInfo sharedInstance].currentBaseURL];

    [MMProgressHUD showWithStatus:@"loading..."];
}

//开始检查是否有固件更新
//进入主界面时会调用
//当本来无internet 后来又有时 在主界面也会发送消息调用
-(void)beginCheckUpdate
{
    if([[[GlobalInfo sharedInstance].currentSelectedUpnPInfo objectForKey:@"internet"] intValue] != 1)
    {
        isGettingUpdate = NO;
        return;
    }
    
    [[GlobalService sharedInstance] beginCheckUpdate:self];
}

-(void)enterDevices:(NSDictionary *)playStatus
{
    AKTabBarController * _tabBarController = [[AKTabBarController alloc] initWithTabBarHeight:(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 70 : 50];
    [_tabBarController setMinimumHeightToDisplayTitle:40.0];
    
    ControlViewController* vc1 = [[ControlViewController alloc] initWithNibName:@"ControlViewController" bundle:nil];
    vc1.playStatusDic = playStatus;
    
    WlanSelectViewController* vc2 = [[WlanSelectViewController alloc] initWithNibName:@"WlanSelectViewController" bundle:nil];
    DeviceMoreViewController* vc4 = [[DeviceMoreViewController alloc] initWithNibName:@"DeviceMoreViewController" bundle:nil];
    MusicViewController * vc3 = [[MusicViewController alloc] initWithNibName:@"MusicViewController" bundle:nil];
    
    UINavigationController * n1 = [[UINavigationController alloc] initWithRootViewController:vc1];
    UINavigationController * n2 = [[UINavigationController alloc] initWithRootViewController:vc2];
    UINavigationController * n3 = [[UINavigationController alloc] initWithRootViewController:vc3];
    UINavigationController * n4 = [[UINavigationController alloc] initWithRootViewController:vc4];
    
    [_tabBarController setViewControllers:[NSMutableArray arrayWithObjects:
                                           n1,
                                           n2,
                                           n3,
                                           n4,nil]];
    
    [self.navigationController pushViewController:_tabBarController animated:YES];
    
    [GlobalInfo sharedInstance].isDisconnect = NO;
}

-(void)prepareUI
{
    UIButton *moreButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [moreButton setBackgroundImage:[UIImage imageNamed:@"morebutton_normal"]
                          forState:UIControlStateNormal];
    [moreButton setBackgroundImage:[UIImage imageNamed:@"morebutton_press"]
                          forState:UIControlStateHighlighted];
    [moreButton addTarget:self action:@selector(moreButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    moreButton.frame = CGRectMake(0, 0, 73, 38);
    
    UIBarButtonItem* rightBtnItem = [[UIBarButtonItem alloc] initWithCustomView:moreButton];
    self.navigationItem.rightBarButtonItem = rightBtnItem;
}

#define max(a,b)    ((a) > (b) ? (a) : (b))
int detectValidWiFi()
{
    int                 i, len, flags;
    char                buffer[4000], *ptr, lastname[16], *cptr;
    struct ifconf       ifc;
    struct ifreq        *ifr, ifrcopy;
    struct sockaddr_in  *sin;
    
   
    int sockfd;
    i = 0;
    
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0)
    {
        perror("socket failed");
        return 0;
    }
    
    ifc.ifc_len = 4000;
    ifc.ifc_buf = buffer;
    
    if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0)
    {
        perror("ioctl error");
        close(sockfd);
        return 0;
    }
    
    lastname[0] = 0;
    
    for (ptr = buffer; ptr < buffer + ifc.ifc_len; )
    {
        ifr = (struct ifreq *)ptr;
        len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);
        ptr += sizeof(ifr->ifr_name) + len;  // for next one in buffer
        
        if (ifr->ifr_addr.sa_family != AF_INET)
        {
            continue;   // ignore if not desired address family
        }
        
        if ((cptr = (char *)strchr(ifr->ifr_name, ':')) != NULL)
        {
            *cptr = 0;      // replace colon will null
        }
        
        if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0)
        {
            continue;   /* already processed this interface */
        }
        
        memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
        
        ifrcopy = *ifr;
        ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);
        flags = ifrcopy.ifr_flags;
        if ((flags & IFF_UP) == 0)
        {
            continue;   // ignore if interface not up
        }
        
        sin = (struct sockaddr_in *)&ifr->ifr_addr;
        if(strcmp(inet_ntoa(sin->sin_addr), "0.0.0.0") == 0
           || strcmp(inet_ntoa(sin->sin_addr), "127.0.0.1") == 0 )
        {
            continue;
        }
        
        i++;
    }
    
    close(sockfd);
    return i;
}

-(void)prepareData
{
    if(detectValidWiFi() <= 0)
    {
        [self.view makeToast:NSLocalizedString(@"ALERT_UNFOUNDWIFI",@"")
                    duration:3.0
                    position:@"bottom"
                       title:NSLocalizedString(@"ALERT_TITLE",@"")];
        
        isWifiConnected = NO;
        
        return;
    }
    isGettingUpdate = NO;
    isWifiConnected = YES;
}

-(void)timerMethod
{
    static int refreshTime = 0;
    
    //下拉刷新
    if(isRefresh == YES)
    {
        if(refreshTime == 0)
        {
            [[WiimuUpnp sharedInstance] refresh];
        }
        
        refreshTime++;
        if(refreshTime > 2)
        {
            refreshTime = 0;
            
            [self stopRefresh];
        }
    }

    //检测wifi连接
    if(detectValidWiFi() > 0)
    {
        if(isWifiConnected == NO)
        {
            isWifiConnected = YES;
        }
    }
    else
    {
        if(isWifiConnected == YES)
        {
            isWifiConnected = NO;

            [self.view makeToast:NSLocalizedString(@"ALERT_UNFOUNDWIFI",@"")
                        duration:3.0
                        position:@"bottom"
                           title:NSLocalizedString(@"ALERT_TITLE",@"")];
        }
    }
    
    //检测更新
    if(isGettingUpdate == YES)
    {
        [self getUpdateStatus];
    }
    
    [menuView reloadData];
}

-(void)stopRefresh
{
    isRefresh = NO;
    [NSThread sleepForTimeInterval:0.5f];
    [_header endRefreshing];

    [MMProgressHUD dismiss];
}

-(void)getUpdateStatus
{
    [[GlobalService sharedInstance] getUpdateState:self];
}

-(void)errorComeBack
{
    dispatch_async(dispatch_get_main_queue(), ^{
        if([GlobalInfo sharedInstance].isDisconnect == NO)
        {
            [GlobalInfo sharedInstance].isDisconnect = YES;
            [[WiimuUpnp sharedInstance] refresh];
            
            [self.view makeToast:NSLocalizedString(@"ALERT_DEVICEDISCONNECT",@"")
                        duration:3.0
                        position:@"bottom"
                           title:NSLocalizedString(@"ALERT_TITLE",@"")];
        }
    });
}

#pragma mark -
#pragma mark servicecallbacks
-(void)serviceGetDeviceInfoCallBack:(NSDictionary*)dicCallBack
{
    [MMProgressHUD dismiss];
    
    NSDictionary * dic = dicCallBack;
    
    if(dic == nil || [[dic objectForKey:@"responsestatus"] intValue] != [SERVICE_SUCCESS intValue])
    {
        [self.view makeToast:NSLocalizedString(@"ALERT_CONNECTTODEVICEFAILED",@"")
                    duration:3.0
                    position:@"bottom"
                       title:NSLocalizedString(@"ALERT_TITLE",@"")];
        
        return;
    }
    
    if([[dic objectForKey:@"expired"] intValue] == 1)
    {
        [self.view makeToast:NSLocalizedString(@"ALERT_VERSIONEXPIRED",@"")
                    duration:3.0
                    position:@"bottom"
                       title:NSLocalizedString(@"ALERT_TITLE",@"")];
        return;
    }
    
    [GlobalInfo sharedInstance].currentSelectedUpnPInfo = dic;
    if([[dic objectForKey:@"netstat"] intValue] == 0)
    {
        [self popWLANView];
    }
    else
    {
        [self getPlayerStatus];
    }
}

-(void)serviceGetPlayerStatusCallBack:(NSDictionary*)dicCallBack
{
    [MMProgressHUD dismiss];
    
    NSDictionary * dic = dicCallBack;
    
    if(dic == nil || [[dic objectForKey:@"responsestatus"] intValue] == [SERVICE_FAIL intValue])
    {
        [self.view makeToast:NSLocalizedString(@"ALERT_GETPLAYSTATEFAILED",@"")
                    duration:3.0
                    position:@"bottom"
                       title:NSLocalizedString(@"ALERT_TITLE",@"")];
        return;
    }
    else if([[dic objectForKey:@"responsestatus"] intValue] == [SERVICE_TIMEOUT intValue] ||
            [[dic objectForKey:@"responsestatus"] intValue] == [SERVICE_CONNECTIONFAIL intValue])
    {
        return;
    }
    
    [self beginCheckUpdate];
    [self enterDevices:dicCallBack];
}

-(void)serviceBeginCheckUpdateCallBack:(NSDictionary*)dicCallBack
{
    NSDictionary * dic = dicCallBack;
    
    if(dic == nil || [[dic objectForKey:@"responsestatus"] intValue] == [SERVICE_FAIL intValue])
    {
        return;
    }
    else if([[dic objectForKey:@"responsestatus"] intValue] == [SERVICE_TIMEOUT intValue] ||
            [[dic objectForKey:@"responsestatus"] intValue] == [SERVICE_CONNECTIONFAIL intValue])
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"PopTabBarController" object:self];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"ErrorComeBack" object:nil];
        return;
    }
    
    isGettingUpdate = YES;
}

-(void)serviceGetUpdateStatusCallBack:(NSDictionary*)dicCallBack
{
    NSDictionary * dic = dicCallBack;
    
    if(dic == nil || [[dic objectForKey:@"responsestatus"] intValue] == [SERVICE_FAIL intValue])
    {
        return;
    }
    else if([[dic objectForKey:@"responsestatus"] intValue] == [SERVICE_TIMEOUT intValue] ||
            [[dic objectForKey:@"responsestatus"] intValue] == [SERVICE_CONNECTIONFAIL intValue])
    {
        return;
    }

    NSString * state = [dic objectForKey:@"updatestate"];
    NSLog(@"updatestatus %@",state);
    if([state hasPrefix:VERSION])
    {
        [[GlobalInfo sharedInstance] setIsVersionNew:YES];
        isGettingUpdate = NO;
    }
    else if([state hasPrefix:READYTOUPDATE])//上一次下载了 重新登录时可能直接进这里
    {
        [[GlobalInfo sharedInstance] setIsVersionNew:NO];
        isGettingUpdate = NO;
        
        [[GlobalService sharedInstance] confirmUpdate:self];
    }
    else if([state hasPrefix:CHECKING])
    {
        isGettingUpdate = YES;
    }
    else
    {
        [[GlobalInfo sharedInstance] setIsVersionNew:NO];
        isGettingUpdate = NO;
    }
}

-(void)serviceConfirmUpdateCallBack:(NSDictionary*)dicCallBack
{}

-(IBAction)testButtonPressed:(id)sender
{
    MPMediaPickerController *picker =
    [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeMusic];

    picker.delegate                     = self;
    picker.allowsPickingMultipleItems   = NO;
    picker.prompt                       = NSLocalizedString (@"Select any song from the list", @"Prompt to user to choose some songs to play");


    @try {
        [picker loadView]; // Will throw an exception in iOS simulator
        [self presentViewController:picker animated:YES completion:nil];
    }
    @catch (NSException *exception) {
        [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Oops!",@"Error title")
                                    message:NSLocalizedString(@"The music library is not available.",@"Error message when MPMediaPickerController fails to load")
                                   delegate:nil
                          cancelButtonTitle:@"OK"
                          otherButtonTitles:nil] show];
    }
}

- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection
{
    [self dismissViewControllerAnimated:YES completion:nil];
//    selectedSongCollection=mediaItemCollection;
}

- (void) mediaPickerDidCancel: (MPMediaPickerController *) mediaPicker
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark - UPNP callbacks
-(void)newDeviceCome:(NSDictionary *)device
{
    [deviceArr addObject:device];
    
    [self.menuView reloadData];
}

-(void)deviceInfoChange:(NSDictionary *)device
{
    for(int i=0; i<[deviceArr count]; i++)
    {
        NSDictionary * dic = [deviceArr objectAtIndex:i];
        
        if([dic[@"friendlyName"] isEqualToString:device[@"friendlyName"]])
        {
            [deviceArr replaceObjectAtIndex:i withObject:device];
            break;
        }
    }
    
    [self.menuView reloadData];
}

-(void)deviceDisappear:(NSDictionary *)device
{
    int i;
    for(i=0; i<[deviceArr count]; i++)
    {
        NSDictionary * dic = [deviceArr objectAtIndex:i];
        
        if([dic[@"friendlyName"] isEqualToString:device[@"friendlyName"]])
        {
            break;
        }
    }
    
    [deviceArr removeObjectAtIndex:i];
    
    [self.menuView reloadData];
}

-(void)netWorkStatusChanged:(Reachability*) curReach
{
    NetworkStatus status = [curReach currentReachabilityStatus];
    
    if(status != ReachableViaWiFi)
    {
        [[WiimuUpnp sharedInstance] stopSSDP];
        
        NSLog(@"请将手机连接到Wi-Fi网络");
        [deviceArr removeAllObjects];
        [self.menuView reloadData];
    }
    else
    {
        [[WiimuUpnp sharedInstance] beginSSDP:devWifiAudio];
    }
}

-(void)allDevicesDisappear
{
    [deviceArr removeAllObjects];
    [self.menuView reloadData];
}

#pragma mark - MJRefreshBaseViewDelegate method
- (void)refreshViewBeginRefreshing:(MJRefreshBaseView *)refreshView
{
    if(refreshView == _header)
    {
        [deviceArr removeAllObjects];
        
        [menuView reloadData];
        
        [self prepareData];
        
        [MMProgressHUD showWithStatus:@"loading..."];
        
        isRefresh = YES;
    }
}

@end
